


11/23/05

	I downloaded the evaluation version of "Rhino3D".
	According to the website, I am capable of 22 saves.

	There after, the evaluation version is fully functional
	except I cannot create or save files.

	The web site also points out that "plug-ins" are fully functional.
	I am not sure I will get to the point actually trying to download
	one of the free plug-ins and trying them.

	I see one purpose for this application (in the very preliminary context
	of evaluating this package):

				As a tool for viewing the "3dm" files that I am going
				to read and write to using the OpenNURBS package.

	Note: I erased the ".exe" installation file that installed this package.


11/23/05 (Addendum)

	I also downloaded the OpenNURBS C++ package.
	
	Documentation for this package is included in the "comments" provided
	in each "example" source directory.

	Here, I am only interested in building the library and using the 
	"read" and "write" example projects.

	Unlike my first encounter with this package a year ago, I do not need to
	concern myself with the Open-GL portion of this package initially.

	I will use Rhino3D as the viewer for the "3dm" files that I am going to create.

	Howerver, I may use the Open-Gl capability later a tool to display (simulate) the
	actual trajectory I generate using the NURBS algorytyms that I am going to create.

	I will also experiment breifly on actually using Rhino3D to create a "3dm"
	file.

	However, I only have a "22 save" limit on this evaluation package so I must
	be judicius in the way I evaluate the creating "3dm" files using this tool.

	Note: I erased the ".zip" installation file that installed this package.


1/15/06

	I reviewed the OpenNURBS projects and associated libraries in "C:\Rhino3D\OpenNurbs".
	The examples are very good.


	For now, I am mostly interested in "example_read", "example_write" and "example_gl".

	I also downloaded the manuals and reference (links) documents (including examples) for OpenGL
	(in "C:\Rhino3D\Project-Documentation\OpenGL-ProgrammingGuide"). My immediate need
	for this information is not important right now.

	I opened "Rhino3D" app. and started poking around. I generated my reference example that
	I am going to use for this entire investigation.

	The file is labeled "my_curves_Rhino3d.3dm" and is stored in "C:\Rhino3D\OpenNurbs\example_files".
	I created this file by making a copy of "my_curves.3dm" in directory "C:\Rhino3D\OpenNurbs\example_files\V3"
	and removing the two circles and straight line.

	What was left was the object named "wiggle" which is a NURB curve that was generated in 3D.

	Remember, this and all the other files in "C:\Rhino3D\OpenNurbs\example_files\V3,..V2,.. and V1"
	were created by the "example_write" project for the various versions
	(V1, V2, and V3) of Rhino3D.

	So what I did was was extend the "wiggle" object with  "arcs" and "lines" and "NURB curves" using
	Rhino3D so as to produce a example 3D application that could be interpolated for motion generation.
	The resulting curve had virtices' tangent to each other such that the complex curve that was made
	of NURB curves, lines and arcs existed in a single plane NOT normal to either the "X", "Y" or "Z"
	plain.

	However, all the curves did exist in a single plane, so that it would make it easier later on
	to evaluate the path velocity in two dimensions.

	To generate these curves, I had to learn a little about the Rhino3D application.

	I descovered what I think is the "snap" equivalent to AutoCad at the bottom of the screen in
	the form of check boxes (such items as "End", "Near", "Point",..ect).

	I used the "near" to connect to each side of the original "wiggle" object and then used menu item
	"Curve->Extend Curve->By Arc and .. By Line" to draw additional segments on each side of "wiggle".

	The "Extend Curve" seem to imply that the extention would start tangent to the existing object you
	are connecting to laying on the plane selected to draw on. 

	There was an existing mesh there that seemed to end up in the plane of "wiggle". 
	
	However, if I looked at the original file "my_curve.3dm", the mesh seemed to be in parallel
	with the circles.

	It must automatic align to the plane in which a single object is draw, if that object itself
	can be defined to lie on a single plane.

	I don't know much about this at this point, and it is certainly not the time to investigate this.

	In any event, this is how I extended the "wiggle" curve.

	In additon, I descovered the menu item "Curve->Free-Form-Interpolate Points" used to draw an 
	arbitrary curve in NURBS. This command is extensively explained in the "Help" reference
	in the "Points and Curves" section.

	The command has auxilary setup states like "StartTangent" that was required to force this curve
	to be draw starting tangent to the beginning of the existing curve and on the plane of the existing
	curve.

	"Degrees" and "Knots" could be also be define here, but I when with the defaults.

	I also discovered "Join" and "Explode" under the "Edit" menu item, which can be used
	to connect all the segments (Join) or seperate the segments of a previously "joined" curve.
	As the "Help" manual stated, these  commands did not effect the geometry of the of the defined
	objects.

	I thing the "Join" was useful for tagging a set of objects as a single object so it could be moved
	around as so forth. However, it's use may be for a more complex minipulation of objects.
	Again, I do not have the time to investigate.

	
		


	.
	.
	.
	.




	I used up "2" saves out of my Rhino3D evaluation application to do this.

	
	
	1/29/06

	I moved the project directory for my original NURBS research (Dec/Jan. of 05/06) to
	"B-Splines (Original Project)". This way all old and new work stays together on my
	backup disks.

	The original "Notes-On-BSpline.txt" is in that directory.

	I need to do things before I jump into the work of actually designing the "NURBS" 
	generation algorythm that would exist on a embedded motion control node.

	First, I need to decide on the algorythm that will be used to calculate the "length"
	of an arbitrary NURBS curve.

	All my intial test code for this work will be done in "C:\Rhino3D\OpenNurbs\example_write\example_write.cpp".

 	I will use the "Arc" example that was converted to NURBS form for testing ideas. 
	This makes it easy to verify the "length" algorythm (curve length of a circle can
	easily be determined by "2*Pi*r" relationship, and this fractions of the circle 
	can be easily determined).

	I discovered by "poking" around the openNURBS library, that a wrapper function
	exists for calculating arc length. This is just a wrapper and has no code.

	I am going to supply the code for this function.
	The wrapper function is named "BOOL ON_NurbsCurve::GetLength()" in file
	"opennurbs_nurbscurve.cpp".

	In "C:\Rhino3D\Project-Documentation\Info-On-Calculating-Curve-Length" I saved two
	documents describing the "Guassian Quadrature" technique for approximating
	integrals.
	
	These files are "Gaussian quadrature-Wikipedia, the free encyclopedia.htm" and
	"Guassian Quadrature.htm".

	Back in "C:\Rhino3D\B-Splines (Original Project)\Documents\Gauss-Integration"
	I reviewed the execelent information I saved on numerical intergration techniques.

	Specificly, the file "First Steps in Numerical Analysis-Gauss.htm".

	The first part of this file "Gauss two-point integration formula" explains
	exactly the method used to determine the "weights" and "abscissae" tables
	shown in the two "htm" files above.

	I studied the information in file "Guassian Quadrature.htm", and created my first
	piece of test code in "example_write.cpp"

	// **** Simple test of "Guassian Quadrature" method to determine length of arc section ****** 

		  int stat;
		  ON_3dVector dp1,dp2;
		  ON_3dPoint p1, p2;

		  double a,b,c,m;
		  double s1,s2;
		  double t1,t2;
		  double Length;

		  a = 0;			  //at 0 degrees of arc (starting point of integration)
		  b = 15.70795/4;	  //at 45 degrees of arc   (calculated "Length" = 3.926673359... , actual length 3.926990816...)
		  //b = 15.70795/6;   //at 30 degrees of arc   (calculated "Length" = 2.55493475... , actual length 2.617993877....)
		  c = (b + a)/2.0;
		  m = (b - a)/2.0;
		   
		  t1 = sqrt(1.0/3.0);
		  t2 = - sqrt(1.0/3.0);
		  

		  stat = Narc2->Ev1Der((c + m*t1), p1, dp1); 
		  s1 = dp1.Length();
		  stat = Narc2->Ev1Der((c + m*t2), p2, dp2);  
		  s2 = dp2.Length();

		  Length = m * (s1 + s2);
		
		  
	// *******************************************************************************************

	Not bad for such a large test segment and only a "3" degree (n = 2) calculation!!!!!!!!

	Note that "Ev1Der()" function provides for finding the derivative of a NURBS curve
	at a given point.

	In "C:\Rhino3D\B-Splines (Original Project)\Application\example.cc" I demonstated the relative
	ease in calculating the derivative of a NURBS equation.

	The general method for doing this is described in "C:\Rhino3D\B-Splines (Original Project)\
	Documents\NurbsNotes\NURBS-Derivatives of a B-spline Curve.htm".

	In the openNURBS library, I think I see this method in "BOOL ON_EvaluateNurbsBasisDerivatives()"
	file "opennurbs_evaluate_nurbs.cpp"



	2/1/06

	Before continuing my basic analysis of the "openNURBS" library functions, I need
	to set up an efficient method of backing any changes I make to the basic
	"Rhino3" project.

	I am going to use the following stratigy because it is simplier than using the CVS
	respository system.

		- I created the directory "BackupDirectoryImage" to hold all changes I make
		  to the "OpenNurbs" source tree.
		
		- A batch file named "BackupOpenNurbsImage.bat" was created and placed in the
		  "BackupDirectoryImage" directory.

		- Each time I start working on (modify) a new file in the "OpenNurbs" source
		  tree, I add an entry to this batch file that will copy this file over
		  to the subdirectory image in the "BackupDirectoryImage" directory. 
		  (I must also manually create the subdirectory in "BackupDirectoryImage")

		- Then, at any given time, I can double click on "BackupOpenNurbsImage.bat" 
		  to backup all by modifications.

		
	2/13/06

		Added project "CurveGenerator".  

		This project is the original "IntroToNurbs-Chap4" project in "B-Splines (Original Project)".
		I copied this directory into "CurveGenerator" and made the following changes:

			- First, all "float" types were changed to "double" to improve accuracy.

			- Removed the files "rbsplinu.c" and "knotu.c" which has to do with the
			  generation of uniform, periodic knot vectors.  It looks like "openNURBS"
			  only generated "open uniform" knots (even the circle is represented as 
			  "open uniform"). The project now consists only of files "trbsplin.c", 
			  "rbspline.c", "rbasis.c" and "knot.c"

			- I added two more parameters to function "rbspline()" ("nknt" and knt[]") to provide the
			  option for explicitly passing the knot vector rather then having function "knot()" 
			  generate a per-unit version internally based on the number of points and "order".

			- modified function "trbsplin.c" to contain a hand written translation of the NURB
			  object contained in file "my_curves_example_write.dmp" (remember this was
			  generated by project "example_write"). In this file, I write some notes
			  on the observation I have made concerning the way "openNURBS" generates the
			  points and knots of each object. MOST IMPORTANTLY, the observation that
			  the values of the knot vector are not simply some arbitrary reference values
			  but instead represent the "lenght of the curve" described.

			- Added code to "trbsplin.c" to generated the file "GenPoints.txt" which is placed
			  in directory "C:\Rhino3D\OpenNurbs\example_files". The idea here is that we
			  are comparing the curve trajectory generation code in project "CurveGenerator" 
			  with "Rhino3d" itself. The check is done by launching "Rhino3d" and opening
			  the file "my_curves_example_write.3dm" (which is generated by "example_write",
			  and for which "example_read" uses to generate "my_curves_example_write.dmp").
			  Then, we select "File->Import" and open the point cloud file "GenPoints.txt".
			  We then see the super-position of the curves from  "my_curves_example_write.3dm"
			  and the points from "GenPoints.txt". The points should be "placed" exactly on
			  top of the curves.
			

	2/21/06 

			Add test code to "example_read.cpp".

			Here we evaluate the method inwhich to open a ".3dm" file created by "Rhino3d"
			and convert it to an another ".3dm" file that strictly defines NURBS.

			The input ".3dm" file can contain "LineCurves" and "ArchCurve" objects,
			as well as "NurbCurve".
			
			After processing, the output ".3dm"	contains only "NurbCurve" objects.	

			The input test file is called "my_curves_Rhino3d.3dm"	and the generated output
			file is "my_curves_Rhino3d_ToAllNurbs.3dm".

			The "example_read" project's "Program Argument" line is setup to generate
			the file "my_curves_Rhino3d_ToAllNurbs.dmp" file after the
			"my_curves_Rhino3d_ToAllNurbs.3dm file is generated.


			I am doing my first back-up here (NURBS_Backup_2_21_06). 

			Along with the usual backup of "BackupDirectoryImage", I will also back-up the
			some other key directorys this first time around.

	3/5/06

			I created the directory "Calculating-Derivative-Of-B-Spline" in the "Project-Documentation"
			directory.

			Within this directory exists "Notes-On-Derivative-Of-B-Spline.txt" that explaines the work
			on verification of the algorythm that represents the derivative of the B-Spline.

			I will need to implement this in one of the projects I am about to create (explained below).
			
			The derivative of the B-Spline follows very closely to the actual algorythm of the 
			B-Spline used in "..\OpenNURBS\CurveGenerator". I will modify this code to create an
			algorythm for the derivative of the B-Spline.

	3/5/06 (Addendium)

			Now comes the work in creating the project necessary to simulate a full implementation
			of the B-Spline processor/executor.

			Two project will be created, "Process3dm" and "Execute3dm".

			"Process3dm" will accept as it's input a ".3dm" containing a mixture of
			NURBS, circle, arc and line objects.

			This project will output:
			
				- a ".3dm" that contains ALL NURBS, including a translation of circle
				  arc, and line object into NURB objects.

				- a ".dmp1" file containing the scripts of all objects contained in the
				  the input ".3dm" file.

				- a ".dmp2" file containing the scripts of all objects contained in the
				  the generated (output) ".3dm" file.
			
				- a ".3dx" file contain the binary version of the objects described in
				  the ".dmp2" file described above. This file will store all parameters
				  associated with each NURB object. Each NURB object will have forward
				  and backward references to their neighboring NURB objects. This will
				  provide the ability for the executor (described below) to read directly
				  from the binary data.

			"Execute3dx" will accept the ".3dx" file described above and read it directly
			into memory (un-altered). This will simulate an actual controllers (like the
			Aerotech Soloist) archive memory (file memory).

			The idea here is there is no intermediated memory for holding the NURB objects.

			To simulate an actual controller's implementation "Execute3dx" will contain
			two threads name "server" and "client" (master and slave).

			The "server" thread will reference the NURBS binary file mentioned above and
			feed NURB object to the "client" thread.

			It will also feed a "reference" to the "client" thread.

			The "client" thread will contain a two level "smart" queue (or buffer) that
			will hold the currently executing NURB object and the NURB object that is
			either ahead or behind the current NURB object.

			The current value of the "reference" sent to the client will determine whether
			the second object is before or after the current object being executed.

			The queue is labeled "smart" because of the necessity of canceling (over-writing)
			the pending object in the buffer if the "reference" is changed in mid-stream while
			operating on the current NURB object (which is at the head of the queue).

			This provides the ability for the "reference" to be reversed in direction 
			(e.g., "backtracing).

			The communcations mode that transfers the NURB objects between "server"
			and "client" will be "bulk" (or asynchronous) using a handshaking
			protocol. This is required because of the way inwhich the "smart"
			queue is to be operated.

			The "reference" will be transfer in "isochronous" mode and will NOT
			be queued. 

			In addition to feeding NURB object and a "reference" to the "client", the
			"server" must itself, generate the reference.

			For now we will NOT provide any "ramping" of the "reference". We will
			simply command a constant speed command.

			The server must execute the "derivative" of the current NURB object
			being executed on the "client".

			At the same time, the server must implement the procedure described in
			document "MovingAtConstant.pdf" in directory "Calculating-Derivative-Of-B-Spline"
			using the derivative of the NURB currently executing and the "constant"
			speed command mentioned above.

			The result of these computations will be the actual "reference" sent to
			the "client"

			The "client" thread will execute the current NURB object at the top of queue
			using the "reference" supplied from the "server".

			The output of the "client" thread will be data points for the "X", "Y", and
			"Z" axis.

			Before the "client" thread is closed, these data points will be transfered
			to a ".txt" file.

			We will then use Rhino3d to compare the original ".3dm" file feed
			to project "Process3dm" with the points stored in this ".txt" file.

	3/7/06

			Created project "Process3dm".
			If I remember right, the VC6 project for OpenNURNBS was converted form and older
			version of VC6.

			I had to dig inorder to get this project to link with the OpenNURBS static
			libraries.

			I included the libraries "opennurbs_static_vc60d.lib" and "zlib_vc60d.lib"
			from directories "DebugStaticLib_vc60" and "zlib\Debug_vc60" (at this point
			I do not know what the "zlib_vc60.lib" does).

			All the sources for "opennurbs_static_vc60d.lib" are in the main directory
			"Rhino3d\OpenNurbs" with the addition of one source "opennurbs_extensions.cpp"
			which is not part of the library.

			This "thru" me because it was not obvious from the original projects (like
			"example_read") that this source had to be included with the project.

			"example_read" has VC6 file "example_read.vcproj". I do not know how
			this was created?. 

			However this setup file (which is a script file) does reference 
			"opennurbs_extensions.cpp" even though it does not show up in
			the VC6 project window?

			In any event, including this file with the librarys listed above into
			"Process3dm" worked. I now have valid project.

			Rememember, the person or persons that designed these libraries had
			an idea of portibility over Unix, Linux, and Windows.

			The "DLL" verions of these libraries could have been used instead.
			In any event, we go with the way it is setup right now.

	3/15/06

			Have completed the sections of "Process3dm.cpp concerning the generation
			of the dump files and the processed ".3dm" file that contains all
			NURBS.	This was relatively easy since most of the work here was
			derived from previous work done in "example_read" and "example_write"
			projects.
			
			
			I am now in the process of constructing function "Generate3dxFile()" in
			file "Process3dm.cpp".
			
			I have written a lengthy description of how this the contents of this
			file will work when used by the project "Execute3dx" (which is yet to
			be created).
			
			This description is in file "Process3dm.cpp"
			
			Now, I will do a backup "NURBS_Backup_3_15_06" which includes the new
			project "Process3dm".


	4/16/06

			Finished the first phase of project "Process3dm". 

			I can generate a ".3dx" file with NURBS curves of "Order 4".

			I am now going to create project "Execute3dm" so that I can
			process the ".3dx".

			I am going to write only enough code in "Execute3dm" to generate a 
			"point cloud", ".txt" file that can be imported into Rhino3d.

			I want to make sure that the methodogy for producing and executing
			the ".3dx" file is sound.

			I will, for the time being, ignore the complex queue design that I outlined
			in file "Process3dm.cpp". I just want enough code to generate the ".txt" file.

			I have fixed file "BackupOpenNurbsImage.bat" to include the "Execute3dm" project
			backup.

			One observtion to make:

			
			File "NurbsCurveArc ()" in file "opennurbs_arccurve.cpp" is the main function
			for converting arcs/circles into NURBS.

			This is a somewhat simple function, and could be easily expanded later to increase
			the "order" and/or "segmentation" of an arc/circle translated into NURBS.

			As I remarked in file "Generate3dx.cpp", the NURBS form produced by "openNURBS" is
			not of the clasical format described in the literature.

			It seems like a special format used to interface to "openGL". 

			As shown in file "trbspline.c" and implemented in file "Generate3dx.cpp", I think
			I have determined the method necessary for translation to the classical form.


	5/14/06

			Backing up:

				NURBS_Backup_5_14_06

	5/16/06

			Have not had a detailed entry (explaination) here for about a month.

			I have been working mostly in file s in files "Execute3dx.cpp", "ClientNode.cpp" and
			"ServerNode.cpp" putting together the code that is going to simulate a master (server)
			and (slave) client operating on the data in "my_curves_Rhino3d.3dx".

			In file "Execute3dx.cpp" I have begun to put together a detailed description of how
			these files are going to operate on the data in "my_curves_Rhino3d.3dx".

			I was just about to work up enough code in these three files to open, process and run the
			".3dx" file.

			For now I am just interested in seeing how the "running" queue that stores ORDER_PACKET's
			was to operate. 

			I do not yet have the code developed to execute the ORDER_PACKET's and place the result
			in the ".xyz" output file.


			I had to stop when I realized the the "knot" vectors in the processed ".3dm" file
			were not exhibiting the correct values.

			My initial assumption was wronge concerning the values of the knot vectors representing
			the length of the curve described.

			It turns out that this is only true for "translated" Arcs, Circles and Lines.

			An additional problem is that some "Lines" to do not covey the correct distances in
			the knots.

			NURBS generated by "freehand" DO NOT covey the lenght of the curve in the values
			of the knot vector.

			If one looks at the "my_curves_Rhino3d.dmp" Lines, Arcs (circles are types or Arcs),
			exhibit a parameter called "domain".

			It is this value range that is inserted into the knots values.

			Sometimes this range represents the the actual distance of the curve (line), and sometimes
			it seems to an arbitrary value.

			The "Rhino3d" help provides a limited explaintion as to the "domain".

			In any event, Lines and Arcs (circles) do provide a parameter for "length".

			As for the "freehand" NURBS, it looks as though I will have to employ numerical intergation
			after all. (see NOTE 1/29/06, above)


			So before I move on, I will insert code in "Process3dm.cpp" where I am converting the input ".3dm"
			file into the processed ".3dm" file, and add code to rescale the knot vector values based on
			the actual calculated distance.

			For the "Lines" and "Arcs", I simply need to call

				((ON_LineCurve *) pOnObject)->GetLength() or

				((ON_ArcCurve *) pOnObject)->GetLength() 

			to get the actual distance.

			For the "freehand" NURBS, I must write the "Guassian Quadrature" algorythm (again, see NOTE 1/29/06, above).



			One final important note.

			Even though the "open_NURBS" library does not provide a finished version of "GetLength()" for
			NURBS objects, Rhino3d does provide the feature for determine lenght of a "freehand" NURBS.

			Just highlight the curve segment and type "lenght" in the command line or use menu "Analyze->Lenght"

			This will provide a verification as to the accuracy of the code I will use to generate the
			"Guassian Quadrature".


	5/21/06

			The problems concerning the errors in some NURBS's knot values as not being
			representitive of "distance" (as outlined in NOTE dated 5/16/06 above), has
			been resolved.

			We now have two ouput dump files, "<file name>_AllNurbs.dmp" (processed but
			knots not adjusted) and 
			"<file name>_AllNurbs_KnotsFixed.dmp" (processed and knots adjusted).


			We know return to project "Execute3dm".

	5/27/06
			Again had to divert back to "Process3dm" project when I descovered that
			the knot vector generation for the ORDER_ELEMENT "pOrderElmt" array 
			was not correct. Also I descovered that the	CV array gereration for "order == 3"
			(arcs, circles) was not correct.

			After and reviewing by test project "CurveGeneration" file "trbsplin.c" throughly,
			I fixed the code in function "GenerateOrderObject()" file "Generate3dx.cpp" of
			project "Process3dm".

			I am pretty sure now that the ORDER_ELEMENT's generated for the "order == 2,3, and 4"
			NURBS is correct.

			Again, I continue to debug project "Execute3dm".


	6/17/05     FINAL BACKUP, WILL RETURN TO THIS PROJECT IN THE FUTURE.

			The entire backup of "Rhino3d" is on CD "Rhino3d Backup #2".
			In addition to the standard backup and selected subdirecties,
			I have "zipped" the entire project for extra measure. 

			I have managed to generate points using the DEBUG_ORDER_ELEMENTS mode
			in file "ServerNode.cpp", function "DebugOrderElements()".

			This debug mode is a prerequiste to finalizing the queue control code
			in function "ServerKernel()" of the same file.

			I have documented some observations as to what is necessary in fixing
			the code in "ServerKernel().

			These observations are listed as comments in function "DebugOrderElements()".

			

